#include <os/lock.h>
#include <os/sched.h>
#include <atomic.h>
#include <sys/binsem.h>
void spin_lock_init(spin_lock_t *lock)
{
    /* TODO */
}

int spin_lock_try_acquire(spin_lock_t *lock)
{
    /* TODO */
}

void spin_lock_acquire(spin_lock_t *lock)
{
    /* TODO */
}

void spin_lock_release(spin_lock_t *lock)
{
    /* TODO */
}

void do_mutex_lock_init(mutex_lock_t *lock)
{
    atomic_swap_d(UNLOCKED,&lock->status);
    queue_init(&(lock->block_queue));
}

void do_mutex_lock_acquire(mutex_lock_t *lock)
{
	int current_cpu = get_current_cpu_id();
    while(lock->status==LOCKED)
		  do_block(&(lock->block_queue));
	lock->status=LOCKED;
	queue_push(&(current_running[current_cpu]->lock_queue),(void*)lock);
}

void do_mutex_lock_release(mutex_lock_t *lock)
{
	int current_cpu = get_current_cpu_id();
    if(!queue_is_empty(&(lock->block_queue))){
		  do_unblock(&(lock->block_queue));
	}
	lock->status=UNLOCKED;
	queue_remove(&(current_running[current_cpu]->lock_queue),(void*)lock);
}
#define UNUSED;
#define BINSEM_LOCK_NUM 16
mutex_lock_t binsem_lock[BINSEM_LOCK_NUM];
int lock_key[BINSEM_LOCK_NUM]={0};
int first_use[BINSEM_LOCK_NUM]={0};
int do_binsemget(int key){
	int lock_id;
	for (lock_id = 0; lock_id < BINSEM_LOCK_NUM&&first_use[lock_id]!=0; ++lock_id){
		if(lock_key[lock_id]==key)
			break;
	}
	if(first_use[lock_id]==0){
		lock_key[lock_id]=key;
		do_mutex_lock_init(&binsem_lock[lock_id]);
		first_use[lock_id]=1;
	}
	return lock_id;
}
int do_binsemop(int binsem_id, int op){
	if(op==BINSEM_OP_LOCK)
		do_mutex_lock_acquire(&binsem_lock[binsem_id]);
	if(op==BINSEM_OP_UNLOCK)
		do_mutex_lock_release(&binsem_lock[binsem_id]);
}
